package com.ruoyi.service.push;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ruoyi.vo.WxPayBean;
import lombok.Synchronized;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;


@Component
public class WxAppletRemoteService {

    private Logger logger = LoggerFactory.getLogger(WxAppletRemoteService.class);

    private static final String WXAPPLETURl="https://api.weixin.qq.com/cgi-bin";

    @Autowired
    private WxPayBean wxPayBean;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ObjectMapper objectMapper;


    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getAppSecret())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        return apiConfig;
    }

    /**
     * 获取AccessToken
     * @return
     */
    @Synchronized
    public String getAccessToken() {
        String appid=null;
        String secret=null;
        // 这里我是从配置文件中取得appid和appsecret
        WxPayApiConfigKit.putApiConfig(getApiConfig());
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
        appid=wxPayApiConfig.getAppId();
        secret=wxPayApiConfig.getMchId();

        // 获取AccessToken的url
        String grantType="client_credential";
        String url=WXAPPLETURl+"/token?grant_type="+grantType+"&appid="+appid+"&secret="+secret;
        // 获取到AccessToken
        String token = restTemplate.getForObject(url, String.class);
        Map<String,Object> map = null;
        try {
            map = objectMapper.readValue(token, Map.class);
        } catch (IOException e) {
            logger.error("小程序异常通知-获取AccessToken-转化异常",e);
        }
        String access_token = String.valueOf(map.get("access_token"));

        if (map.get("errcode")!=null || map.get("errmsg")!=null){
            String errcode = String.valueOf(map.get("errcode"));
            String errmsg = String.valueOf(map.get("errmsg"));
            if (!errcode.equals("0")){
                logger.error("获取token失败：code="+errcode+"msg="+errmsg);
                return null;
            }
        }
        return access_token;
    }

    /**
     * 同一消息发送接口
     * AppletTemplateMessageSendDTO   是一个传输类
     */
    public String uniformMessageSend(Object data) {
        String token = getAccessToken();
        // 调用发型接口
        String url=WXAPPLETURl+"/message/subscribe/send?access_token="+token;
        // 解决服务推送中文乱码问题
        HttpHeaders headers = new HttpHeaders();
        MediaType headType = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(headType);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        //  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        HttpEntity<String> requestEntity = new HttpEntity<String>(data.toString(), headers);
        // 发送消息推送
        String returnData = restTemplate.postForObject(url, data, String.class);
        Map<String,Object> map = null;
        try {
            map = objectMapper.readValue(returnData, Map.class);
        } catch (IOException e) {
            logger.error("小程序异常通知-同一消息发送-转化异常",e);
        }
        String errcode = String.valueOf(map.get("errcode"));
        String errmsg = String.valueOf(map.get("errmsg"));
        if (!errcode.equals("0")){
            logger.error("消息发送失败：code="+errcode+"; msg= "+errmsg);
        }
        return errcode;
    }

}
